package engine.core
{
	import flash.utils.*;
	
	public class RxObjectPool extends Object
	{
		private var m_allocFunc:Function;
		private var m_freeFunc:Function;
		private var m_pool:Vector.<Object>;
		private var m_numFree:uint;
		private var m_growSize:uint;
		private var m_className:String;
		
		public function RxObjectPool(allocFunc:Function, freeFunc:Function, numFree:uint, growSize:uint, className:Class)
		{
			this.m_allocFunc = allocFunc;
			this.m_freeFunc = freeFunc;
			this.m_pool = new Vector.<Object>(numFree, false);
			this.m_numFree = numFree;
			
			var i:int = 0;
			while (i < numFree)
			{
				
				this.m_pool[i] = this.m_allocFunc();
				i = i + 1;
			}
			this.m_growSize = growSize;
			this.m_className = getQualifiedClassName(className);
		}
		
		public function Alloc() : Object
		{
			if (this.m_numFree == 0)
			{
				if (this.m_growSize)
				{
					this.Grow(this.m_growSize);
				}
				else
				{
					return null;
				}
			}
			
			var obj:Object = m_pool[--m_numFree];
			this.m_pool[m_numFree] = null;
			return obj;
		}
		
		public function Free(obj:Object) : void
		{
			if (obj != null)
			{
				if (this.m_freeFunc != null)
				{
					this.m_freeFunc(obj);
				}
				
				var index:int = this.m_numFree++;
				m_pool[index] = obj;
			}
		}
		
		public function Grow(index:uint) : void
		{
			
			RxLog.Warning(this.m_className + " object pool is growing from " + this.m_pool.length + " by " + index + ". There\'s either a leak, or the pool should\'ve been larger.");
			this.m_pool.length = this.m_pool.length + index;
			
			var i:uint = 0;
			while (i < index)
			{
				
				this.m_pool[this.m_numFree + i] = this.m_allocFunc();
				i = i + 1;
			}
			
			this.m_numFree = this.m_numFree + index;
		}
		
		public function Delete() : void
		{
			var i:uint = 0;
			while (i < this.m_pool.length)
			{
				
				if (this.m_pool[i] != null)
				{
					if (this.m_freeFunc != null)
					{
						this.m_freeFunc(this.m_pool[i]);
					}
					this.m_pool[i] = null;
				}
				
				i = i + 1;
			}
			
			this.m_pool.length = 0;
			this.m_pool = null;
			this.m_allocFunc = null;
			this.m_freeFunc = null;
			this.m_numFree = 0;
			this.m_growSize = 0;
		}
	}
}
